﻿using CommonTools;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
using shop.Model;
using shop.Web.hub;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace shop.Web.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class JobsController : ControllerBase
    {
        private readonly IFreeSql _sql;

        public JobsController(IFreeSql sql)
        {
            _sql = sql;
        }


        [HttpGet]
        public async Task<IEnumerable<BackgroundJob>> QueryJobs(string user, int jobId =0)
        {
            var list = await _sql.Select<BackgroundJob>()
                .Where(a=> a.Isdel== false)
                .WhereIf(jobId >0, a=> a.id== jobId)
                .OrderByDescending(a=>a.CreateTime)
                .Take(50)
                .ToListAsync();

            foreach (var job in list) 
            { 
                if(job.IsCompleted == false || job.IsFailed == true)
                {
                    job.FileLink = null;
                }
            }

            return list;
        }


        [HttpPost]
        public async Task<string> CreateJob([FromBody] BackgroundJob job)
        {
            var guid = Guid.NewGuid().ToString("N");
            job.JobId = guid;
            job.CreateTime= DateTime.Now;   
            job.IsCompleted = false;
            job.Isdel = false;
            
            //_jobs.Add(job);

            await _sql.Insert(job).ExecuteAffrowsAsync();

            return guid;
        }

        [HttpGet]
        public async void MakeJobDone(string jobid, bool isFailed, string fileLink, string failReason,
            [FromServices] IHubContext<UserJobsHub> hubContext)
        {

            if(string.IsNullOrEmpty(failReason) == false && failReason.Length>500)
            {
                failReason = failReason.Substring(0, 500);
            }

            await _sql.Update<BackgroundJob>()
                .Where(a => a.Isdel == false && a.JobId == jobid)
                .Set(a => a.IsCompleted == true)
                .Set(a => a.IsFailed == isFailed)
                .SetIf(!string.IsNullOrEmpty(fileLink), a=> a.FileLink, fileLink)
                .Set(a => a.DoneTime == DateTime.Now)
                .Set(a=> a.FailReason, failReason)
                .ExecuteAffrowsAsync();

            //推送消息
            var uid = await _sql.Select<BackgroundJob>()
                .Where(a => a.Isdel == false && a.JobId == jobid)
                .ToOneAsync(a => new { a.UserId, a.id, a.JobName });

            if(uid != null && UserJobsHub._users.TryGetValue(uid.UserId, out var conId))
            {
                await hubContext.Clients.User(conId).SendAsync("JobDone", 
                    new Result<int>(!isFailed, isFailed 
                    ? $"您有后台任务:{uid.JobName} 执行失败!\n{failReason}"
                    : $"您有后台任务:{uid.JobName} 执行成功!", 
                    uid.id));
            }
        }


        [HttpGet]
        public async Task TestMessage([FromServices] IHubContext<UserJobsHub> hubContext)
        {
            if ( UserJobsHub._users.TryGetValue("1", out var conId))
            {
                await hubContext.Clients.Client(conId).SendAsync("JobDone", new Result<int>(false, "您的任务执行完成", 9063));
            }
        }


    }
}
